package org.leviatan.definator.core.admin;

import java.util.Collection;
import java.util.HashMap;

import org.leviatan.definator.core.DefinatorConfiguration;
import org.leviatan.definator.core.model.Field;
import org.leviatan.definator.core.model.Record;
import org.leviatan.definator.core.model.Table;

public class DefinatorAdminServiceImpl implements DefinatorAdminService {

	private static DefinatorAdminServiceImpl instance = null;
	
	private DefinatorAdminServiceImpl() { }
	
	public static DefinatorAdminService getService() {
		if (DefinatorAdminServiceImpl.instance == null) {
			DefinatorAdminServiceImpl.instance = new DefinatorAdminServiceImpl();
		}
		return DefinatorAdminServiceImpl.instance;
	}
	
	public void loadModels() {
		RegistryHandler.loadTableModels();
		RegistryHandler.loadRecordModels();
		RegistryHandler.loadFieldModels();
	}
	
	public void saveModels() {
		RegistryHandler.saveTableModels();
		RegistryHandler.saveRecordModels();
		RegistryHandler.saveFieldModels();
	}
	
	public void loadRegister() {
		this.loadModels();
		RegistryHandler.prepareFld2RecMap();
		RegistryHandler.prepareRec2FldsMap();
		RegistryHandler.prepareRec2TblMap();
		RegistryHandler.prepareTbl2RecsMap();
	}

	public void loadConfiguration(String filePath) {
		DefinatorConfiguration config = 
			DefinatorConfigurationHandler.factorNewConfiguration(filePath);
		
		DefinatorConfigurationHandler.setActiveConfiguration(config);
	}
	
	public HashMap getFieldDefinitions() {
		return RegistryHandler.getFieldModels();
	}

	public Field getFieldModel(String aId) {
		return RegistryHandler.getFieldModel(aId);
	}

	public HashMap getRecordDefinitions() {
		return RegistryHandler.getRecordModels();
	}

	public Record getRecordModel(String aId) {
		return RegistryHandler.getRecordModel(aId);
	}

	public Collection getRecordsFieldIds(String recId) {
		return RegistryHandler.getRecordsFieldIds(recId);
	}

	public HashMap getTableDefinitions() {
		return RegistryHandler.getTableModels();
	}

	public Table getTableModel(String aId) {
		return RegistryHandler.getTableModel(aId);
	}

	public Collection getTablesRecordIds(String tblId) {
		return RegistryHandler.getTablesRecordIds(tblId);
	}
	
	public String getFieldsRecordId(String fldId) {
		return RegistryHandler.getFieldsRecordId(fldId);
	}

	public String getRecordsTableId(String recId) {
		return RegistryHandler.getRecordsTableId(recId);
	}

	
	// removes & adds
	///////////////////////////////////////////////////////////////////////////
	
	public Field addFieldModel(Field fld) {
		return RegistryHandler.addFieldModel(fld);
	}

	public Record addRecordModel(Record rec) {
		return RegistryHandler.addRecordModel(rec);
	}

	public Table addTableModel(Table tbl) {
		return RegistryHandler.addTableModel(tbl);
	}

	public boolean removeFieldModel(String fldId) {
		return RegistryHandler.removeFieldModel(fldId);
	}

	public boolean removeRecordModel(String recId) {
		return RegistryHandler.removeRecordModel(recId);
	}

	public boolean removeTableModel(String tblId) {
		return RegistryHandler.removeTableModel(tblId);
	}
	
	// updates & creations
	///////////////////////////////////////////////////////////////////////////
	
	public boolean updateFieldModel(String fldId, Field fldModel) {
		FieldHandler.setFieldModel(fldId);
		return FieldHandler.updateField(fldModel);	
	}

	public boolean updateRecordModel(String recId, Record recModel) {
		RecordHandler.setRecordModel(recId);
		return RecordHandler.updateRecord(recModel);
	}

	public boolean updateTableModel(String tblId, Table tblModel) {
		TableHandler.setTableModel(tblId);
		return TableHandler.updateTable(tblModel);
	}

	public boolean updateFieldLength(String fldId, int newLength) {
		return FieldHandler.updateFieldLength(fldId, newLength);
	}

	public boolean updateFieldModel(String fldId, String newName, int newLength, String newType, String newRef) {
		return FieldHandler.updateField(fldId, newName, newLength, newType, newRef);
	}

	public boolean updateFieldName(String fldId, String newName) {
		return FieldHandler.updateFieldName(fldId, newName);
	}

	public boolean updateFieldRecordRef(String fldId, String newRef) {
		return FieldHandler.updateFieldRecordRef(fldId, newRef);
	}

	public boolean updateFieldType(String fldId, String newType) {
		return FieldHandler.updateFieldType(fldId, newType);
	}

	public boolean updateRecordName(String recId, String newName) {
		return RecordHandler.updateRecordName(recId, newName);
	}

	public boolean updateTableName(String tblId, String newName) {
		return TableHandler.updateTableName(tblId, newName);
	}

	public String createNewFieldModel(String name, int length, String type, String recRef) {
		Field fld = FieldHandler.createNewField();
		FieldHandler.setFieldModel(fld);
		FieldHandler.setFieldName(name);
		FieldHandler.setFieldRecordRef(recRef);
		FieldHandler.setFieldLength(length);
		FieldHandler.setFieldType(type);
		// TODO check id dups!
		
		RegistryHandler.addFieldModel(fld);
		
		RegistryHandler.saveFieldModels();
		return fld.getId();
	}

	public String createNewRecordModel() {
		Record rec = RecordHandler.createNewRecord();
		RegistryHandler.addRecordModel(rec);
		RegistryHandler.saveRecordModels();
		return rec.getId();
	}

	public String createNewRecordModel(String name, String tblRef) {
		Record rec = RecordHandler.createNewRecord();
		RecordHandler.setRecordModel(rec);
		RecordHandler.setRecordName(name);
		RecordHandler.setRecordTableRef(tblRef);
		RegistryHandler.addRecordModel(rec);
		RegistryHandler.saveRecordModels();
		return rec.getId();
	}

	public String createNewTableModel() {
		Table tbl = TableHandler.createNewTable();
		RegistryHandler.addTableModel(tbl);
		RegistryHandler.saveTableModels();
		return tbl.getId();
	}

	public String createNewTableModel(String name) {
		Table tbl = TableHandler.createNewTable();
		TableHandler.setTableModel(tbl);
		TableHandler.setTableName(name);
		RegistryHandler.addTableModel(tbl);
		RegistryHandler.saveTableModels();
		return tbl.getId();
	}

	public String createNewFieldModel() {
		Field fld = FieldHandler.createNewField();
		RegistryHandler.addFieldModel(fld);
		
		RegistryHandler.saveFieldModels();
		return fld.getId();
	}
	
	

	
	///////////////////////////////////////////////////////////////////////////

	
	
	
	///////////////////////////////////////////////////////////////////////////
	
	

}
